// ObjectTracking.cpp : Defines the entry point for the console application.
//

//#define _CRTDBG_MAP_ALLOC
#include "stdafx.h"

/* GPU Garbor */
//# define MODE_TRIGGER

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//#include <cutil_inline.h>
#include <math.h>
//#include <cxcore.h>
//#include <highgui.h>  //opencv 
/////////////////////////////////////
#include <iostream>
#include <fstream>
#include <list>

//using namespace std;

//#include "gabor.h"   //gpu configration
/*  GPU Garbor  */

#include <tbb/tbb.h>
#include <tbb/mutex.h>
#include <time.h>
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include "video.h"
#include "Frame.h"
#include "MotionTemplate.h"
#include "GaussianBGModel.h"
#include "HoughTransform.h"
#include "SiftGPU.h"

#include "SIFTFeature.h"
#include "SURFeatures.h"
#include <glew.h>
#include <exception>

#include <direct.h>

//#include "opencv2/core/core.hpp"
//#include "opencv2/gpu/gpu.hpp"

//#include "pthread.h"  // http://www.intuvisiontech.com/enews-10l.html

//#include <omp.h>

// CUDA-C includes
#include <cuda.h>
/*#include <cuda_runtime_api.h>*/
#include <cutil_inline.h>
#include "DBConnect.h"
#include "gabor.h"   //gpu configration


/////#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <time.h>

//#include "mem.h"
//#include "Denomo.h"
//#include <stdexcept>
#include "IL/il.h"
#include "ObjectTracker.h"

using namespace std; 
using namespace tbb;
using namespace cv;



//cv::mutex cameraMutex
tbb::mutex cameraMutex;
tbb::mutex gpuMutex;
//pthread_mutex_t mutexPT = PTHREAD_MUTEX_INITIALIZER;
//IplImage** imageArray;
Frame** frameArray;
Video** videoCollection=0;
MotionTemplate** motionTemplateCollection=0;
Complexgf** previousResult=0;
IplImage** previousImage=0;
int* pYMaxArray=0;

vector<Point> points;
int* frameNoGlobal=0;

unsigned char* srcOneBefore=0;
unsigned char* srcTwoBefore=0;
/*Video* videoCollectioin[20];
MotionTemplate* motionTemplateCollection[20];
Frame* frameCollection[20];*/

// declaration, forward
//extern "C" bool imageCopy(unsigned char* src,unsigned char* dest,int width,int height,size_t size,int noOfImages);
extern "C" bool imageCopy(unsigned char* src,unsigned char* srcOneBefore,unsigned char* srcTwoBefore,unsigned char* dest,int width,int height,size_t size,int noOfImages);

extern "C" bool imageCharToFloat(float *imageDataFloat,char *imageDataChar,int widthStep,int width,int height);
extern "C" bool gaborDistance(float *data_energy,Complexgf *resultPrevious,Complexgf *resultNow,int width,int height);
extern "C" bool frontMovingSegment(float *d_data_energy,int* d_minColLocation,int* d_maxColLocation,int width,int height);

bool imageCopyCPU(unsigned char* src,unsigned char* dest,int width,int height,size_t size,int noOfImages);

//extern "C" void euclideanDistance(float* descriptorsObject,size_t descriptorsObjectSize,float* descriptorImage, size_t descriptorImageSize);
//extern "C" void euclideanDistance();

 /* 
  //Used for pThreads
void* fetchFrames( void* args )
{
      int ip=(int)args;
      char ipAddress[50];
      sprintf(ipAddress,"192.248.%d.0",(ip+2));

      try
       {
           // for(;;)
            {
               // printf("%d\n",ip);
            }
            clock_t start,end;
       
            char fileName[150];
           
      
           sprintf(fileName,"E:\\CUDA\\Project\\Samples\\192.248.%d.0.asf",(ip+2));
     
            if(videoCollection[ip]==0)
            {
                
                videoCollection[ip] = new Video();
                 
		

               // cameraMutex.lock();
               pthread_mutex_lock(&mutexPT);
                videoCollection[ip]->captureFromFile(fileName);
                pthread_mutex_unlock(&mutexPT);
     
               // cameraMutex.unlock();                     
               
            }
              for(;;)
              {
                    Frame* frame = new Frame();
                        
                    cameraMutex.lock();
                    frame->setFrame(videoCollection[ip]->queryFrame()); 
                    cameraMutex.unlock();
                    
                    frameNoGlobal[ip]++;
                    frame->setFrameNo(frameNoGlobal[ip]);
                    //printf("Frame No:%d\n",frame->getFrameNo());
                   
                  // cameraMutex.lock();
                    frameArray[ip] = frame;
                    
                    if(frame->getFrame())
                    {
                       frame->showFrame(frame->getGrayFrame());
                    
                    }
                    else
                    {
			            printf("Error Querying Frame on : %s\n",ipAddress);                    
                    }
               }
                
                
     } 
    catch(exception& e)
    {
        printf("Exception on Thread ip Address: %s, Error:%s",ipAddress,e.what());
    }
    return NULL;

}  */
struct update
{
    void operator()( const tbb::blocked_range<int>& r ) const
    {
        for( int ip=r.begin(); ip!=r.end(); ++ip )
            //for(int ip=0;ip<20;ip++)
        {
        
        
            char ipAddress[50];
           sprintf(ipAddress,"192.248.%d.0",(ip+10));
         //sprintf(ipAddress,"192.248.%d.0",10);
          try
           {
                clock_t timeStart,timeEnd, gpuTimeStart,gpuTimeEnd,gpuTimeSURFStart,gpuTimeSURFEnd;
                //string fileName="E:\\CUDA\\Project\\Samples\\03.asf";
                char fileName[150];
               
               // char fileName = 
                
                //sprintf(ipAddress,"192.248.%d.0",2);
                //sprintf(ipAddress,"192.248.%d.0",ip);
                //sprintf(ipAddress,"192.248.8.5",ip);   192.248.7.0
               sprintf(fileName,"E:\\CUDA\\Project\\Samples\\192.248.%d.0.asf",(ip+10));
              ///sprintf(fileName,"E:\\CUDA\\Project\\Samples\\192.248.%d.0.asf",10);
    		
               // cameraMutex.lock();
                if(videoCollection[ip]==0)
                {
                    
                    videoCollection[ip] = new Video();
                     
			        //Video* video = new Video();

                    //videoCollectioin[ip]->captureFromFile(fileName);

                    cameraMutex.lock();
                    videoCollection[ip]->captureFromFile(fileName);
                    //videoCollectioin[ip]->captureFromCAM(ip);
                    cameraMutex.unlock();
                   
                }
                //cameraMutex.unlock();
                

                float omega = (float)2*PI/16;  // was 2*PI/16
                float phi = (float)(PI*6/8);  //orientation  was *0/8 2   6
                // float phi = (float)(1.005*PI/2);
                //float phi = (float)(1.005*0/8);  //orientation  was *0/8
                

                float sigmau = (float)2/omega;   //minor axis
                float sigmav = (float)2*sigmau;  //major axis

                // parameter of center surround filter	
                float sigma_surround = (float)sigmau;
                float sigma_center = (float)sigma_surround / 2;
    	        
                //create Filter_kernel objects for center surround filter
                Filter_kernel gaussian_kernel_c(sigma_center, sigma_center, 0);
                Filter_kernel gaussian_kernel_s(sigma_surround, sigma_surround, 0);

                //create a Filter_kernel objects for Gabor filter
                Filter_kernel gabor_kernel(sigmav, sigmau, phi, omega);
                
                
                
                SURFeatures surf;
                for(;;)
                {
                    /*char outputFileName[40];
                    sprintf(outputFileName,"output10_3.txt");
                    ofstream outPutFile;
                    outPutFile.open (outputFileName, ios::app);               */
		            timeStart = clock();
    		        
    		      
                    
                    // used in frame rate control start = clock();
                    //double tt=(double)cvGetTickCount();
                    double sec=0.0;

                   
                    
                    Frame* frame = new Frame();
                    
                   cameraMutex.lock();
                   frame->setFrame(videoCollection[ip]->queryFrame()); 
                   cameraMutex.unlock();
                    
                    frameNoGlobal[ip]++;
                    frame->setFrameNo(frameNoGlobal[ip]);
                   // printf("Frame No:%d\n",frame->getFrameNo());
                   
                  // cameraMutex.lock();
                    frameArray[ip] = frame;
                  // cameraMutex.unlock(); 
                    
                    if(frameNoGlobal[ip]==2000)
                    {
                        exit(0);
                       // printf("End\n");
                    }
                    //frameArray[j] = frame;
                    
                    if(frame->getFrame())
                    { 
                        /*Gabor Filter GPU*/
                        // DEFINE FILTER PARAMETERS AND COMPUTE KERNELS	
	                    //parameter of gabor filter
	                   /*  float omega = (float)2*PI/16;  // was 2*PI/16
                        float phi = (float)(PI*6/8);  //orientation  was *0/8 2   6
                        // float phi = (float)(1.005*PI/2);
                        //float phi = (float)(1.005*0/8);  //orientation  was *0/8
                        

                        float sigmau = (float)2/omega;   //minor axis
                        float sigmav = (float)2*sigmau;  //major axis

                        // parameter of center surround filter	
                        float sigma_surround = (float)sigmau;
                        float sigma_center = (float)sigma_surround / 2;
            	        
                        //create Filter_kernel objects for center surround filter
                        Filter_kernel gaussian_kernel_c(sigma_center, sigma_center, 0);
                        Filter_kernel gaussian_kernel_s(sigma_surround, sigma_surround, 0);

                        //create a Filter_kernel objects for Gabor filter
                        Filter_kernel gabor_kernel(sigmav, sigmau, phi, omega);   */
    	                
	                   /* if(frameNoGlobal[ip]<36306)
	                    {
	                        delete frame; 
	                        continue;
	                                          
	                    } */
    	                
    	                
	                   float *imag;
	                  // char *charImage;
	                   //  cameraMutex.lock();
	                    IplImage *pImage=frameArray[ip]->getGrayFrame();
	                    IplImage *pImageReSized;
	                    
	                   // cvShowImage("Original",frameArray[ip]->getFrame());
	                  //    cameraMutex.unlock();
            	        if(pImage!=0)
    	                {   
    	                
    	                    int imageWidth = pImage->width;
    	                    int imageHeight = pImage->height;
    	                    //int roiHeightLocation = pImage->height*0.4;
    	                    int roiImageHeight =   pImage->height*.7;
    	                    
    	                    cvSetImageROI(pImage,cvRect(0,imageHeight-roiImageHeight,imageWidth*0.6,roiImageHeight));
    	                    pImageReSized = cvCreateImage(cvSize(imageWidth*0.6,roiImageHeight),IPL_DEPTH_8U, 1);
		                    cvCopy(pImage,pImageReSized); 			       
		                    cvResetImageROI(pImage);
		                    
		                   /* cvShowImage("Re-sized", pImageReSized);
		                      cvWaitKey(1);*/
		                    
		                    //char ipAddress[50];
                          //  sprintf(ipAddress,"Original_192.248.%d.0",(ip+10));
		                    /*
		                  //  IplImage* tempPImageReSized=cvCreateImage(cvSize(pImageReSized->width/2,pImageReSized->height/2),IPL_DEPTH_8U, 1);
		                    pImageReSized=  cvCreateImage(cvSize(pImageReSizedTemp->width/2,pImageReSizedTemp->height/2),IPL_DEPTH_8U, 1);
		                    cvResize(pImageReSizedTemp,pImageReSized,CV_INTER_NN);
		                   // cvShowImage(ipAddress,pImageReSized);
		                    // cvWaitKey(1);
		                 //    cvReleaseImage(&tempPImageReSized);
		                   cvReleaseImage(&pImageReSizedTemp);*/
		                    
		                        
		                        
    	                     
    	                      /* cv::Mat  pImageReSizedCharMat = cv::Mat(pImageReSized,false);
    	                       cv::Mat  pImageReSizedFloatMat;
    	                       pImageReSizedCharMat.convertTo(pImageReSizedFloatMat,CV_32FC1);*/
    	                     
    	                      /*
    	                      
    	                    cv::gpu::GpuMat pImageGPUMatSrc,pImageGPUMatDst,pImageGPUFloatDstMat;
    	                   
    	                    cv::Mat pImageReMat,pImageMat = cv::Mat(pImageReSized,true);
    	                    gpuMutex.lock();
    	                    pImageGPUMatSrc.upload(pImageMat);
    	                   // cvWaitKey(2);       	                    
    	                    cv::gpu::resize(pImageGPUMatSrc,pImageGPUMatDst,cvSize(pImage->width/2,pImage->height/2),0,0,INTER_LINEAR);
    	                   // imshow("Re-sized",(cv::Mat)pImageGPUMatDst);
    	                   pImageReMat = (cv::Mat)pImageGPUMatDst;                     
    	                    
    	                    // gpuMutex.unlock();
    	                    //pImageGPUMatDst.convertTo(pImageGPUFloatDstMat,CV_32FC1);
    	                 
    	                    pImageGPUMatDst.~GpuMat();
    	                    pImageGPUMatSrc.~GpuMat();
    	                    gpuMutex.unlock();      	                    
    	                    
    	                    cvReleaseImage(&pImageReSized);
    	                    pImageReSized = new IplImage(pImageReMat);
    	                    cvShowImage("Re-sized",pImageReSized);
    	                    cvWaitKey(1);
    	                         */
    	                   // *pImageReSized= pImageReMat;
    	                       
    	                    //cvShowImage("Re-sized",pImageReSized);
    	                    //cvWaitKey(2);
    	                    int resizedImageWidth = pImageReSized->width;
    	                    int resizedImageHeight = pImageReSized->height;
    	                        	                    
    	                   //  gpuMutex.lock();
	                       // cutilSafeCall( cudaMallocHost( (void **)&imag, pImage->width* pImage->height * sizeof(float)));
	                        /*cutilSafeCall( cudaMallocHost( (void **)&imag, resizedImageWidth * resizedImageHeight * sizeof(float)));
	                       // cutilSafeCall( cudaMemcpy( (void **)&imag,(float*)pImageReSizedFloatMat.data,resizedImageWidth * resizedImageHeight * sizeof(float),cudaMemcpyHostToHost));
	                        
	                        float *d_imageDataFloat;
	                        char *d_imageDataChar;
	                        
	                        //move down to the locks
	                        cutilSafeCall( cudaMalloc( (void **)&d_imageDataFloat, resizedImageWidth * resizedImageHeight * sizeof(float)));
	                        cutilSafeCall( cudaMalloc( (void **)&d_imageDataChar, pImageReSized->widthStep * resizedImageHeight * sizeof(char)) );
	                        cutilSafeCall(cudaMemcpy(d_imageDataChar, pImageReSized->imageData, pImageReSized->widthStep * resizedImageHeight * sizeof(char), cudaMemcpyHostToDevice));              	                            
	                        
	                        imageCharToFloat(d_imageDataFloat,d_imageDataChar,pImageReSized->widthStep,resizedImageWidth,resizedImageHeight);
	                         
                             cutilSafeCall(cudaMemcpy(imag, d_imageDataFloat,resizedImageWidth * resizedImageHeight * sizeof(float), cudaMemcpyDeviceToHost));              	                            
                             
                             cutilSafeCall(cudaFree(d_imageDataFloat));
                	         cutilSafeCall(cudaFree(d_imageDataChar));
                	         */
	                       /* cutilSafeCall( cudaMallocHost( (void **)&charImage, resizedImageWidth * resizedImageHeight * sizeof(char)));
	                        
	                         cutilSafeCall(cudaMemcpy(d_resultPrevious, previousResult[ip], resizedImageWidth*resizedImageHeight*sizeof(Complexgf), cudaMemcpyHostToDevice));              	                            
	                        imageCharToFloat(imag,pImageReSized->imageData,pImageReSized->widthStep,resizedImageWidth,resizedImageHeight);
	                         */
	                        //cutilSafeCall( cudaMemcpy(imag, (float*)pImageReSized->imageData, resizedImageWidth * resizedImageHeight * sizeof(float), cudaMemcpyHostToDevice ));
	                       // imag = (float*) pImageGPUFloatDstMat.data;
	                       /* for(int y = 0; y < resizedImageHeight; y ++)
	                        {
		                        for(int x = 0; x < resizedImageWidth; x ++)
		                        {
			                        imag[y*pImageReSized->width+x] = (float)(unsigned char)pImageReSized->imageData[y*pImageReSized->widthStep+x];
			                       
			                      //  imag[y*pImageReSized->width+x] = (float)(unsigned char)pImageReMat.data[y*pImageReSized->widthStep+x];
			                        //imag[y*pImage->width+x] = (float)(unsigned char)pImageReMat.data[y*resizedImageWidth+x];
			                       //imag[y*pImage->width+x] = 10;
		                        }
		                    }
		                    */
        		            
        		           gpuTimeStart = clock();
		                    Complexgf *result; 
	                        cutilSafeCall( cudaMallocHost( (void **)&result, resizedImageWidth* resizedImageHeight * sizeof(Complexgf)));
	                        
	                        /*float* data_energy;
        		           cutilSafeCall( cudaMallocHost( (void **)&data_energy, resizedImageWidth* resizedImageHeight * sizeof(float)));
        		           */   
        		           int *minColLocation,*maxColLocation;  	                            
        		           cutilSafeCall( cudaMallocHost( (void **)&minColLocation,resizedImageHeight * sizeof(int)));
        		           cutilSafeCall( cudaMallocHost( (void **)&maxColLocation,resizedImageHeight * sizeof(int)));
        		           
    		                 
		                    //Gabor* gabor = new Gabor(pImage->width,pImage->height);
		                    Gabor gabor(resizedImageWidth,resizedImageHeight,1);
            	        
	                        //ALLOCATE GPU MEMORY FOR PARAMETERS FOR PROCESSING
	                          int 
	                            *d_minColLocation,
	                            *d_maxColLocation;
	                            
	                         char *d_imageDataChar;

	                        float
		                        *d_DataA_unpad,
		                        *d_DataA,
		                        *d_data_energy;

	                        Complexgf
		                        *d_padimgresult,
		                        *d_ResultGPU,
		                        *d_resultPrevious;
		                        
                		    gpuMutex.lock();   
		                    cutilSafeCall( cudaMalloc( (void **)&d_DataA_unpad, gabor.DATA_SIZE_ori_f));
	                        cutilSafeCall( cudaMalloc( (void **)&d_DataA, gabor.DATA_SIZE_pad_f) );
	                        cutilSafeCall( cudaMalloc( (void **)&d_padimgresult, gabor.DATA_SIZE_pad_c));
	                        cutilSafeCall( cudaMalloc( (void **)&d_ResultGPU, gabor.DATA_SIZE_ori_c));   
	                        
                           //added for calcutate the distance
                            cutilSafeCall( cudaMalloc( (void **)&d_data_energy, gabor.DATA_SIZE_ori_f));
                            cutilSafeCall( cudaMalloc( (void **)&d_resultPrevious, gabor.DATA_SIZE_ori_c)); 
                            
                            //to find the ROI
                            cutilSafeCall( cudaMalloc( (void **)&d_minColLocation,sizeof(int)*resizedImageHeight ));
                            cutilSafeCall( cudaMalloc( (void **)&d_maxColLocation,sizeof(int)*resizedImageHeight )); 
	                       
                            
                            // PERFORM THE CENTER SURROUND AND GABOR FILTERING
                		
	                        // transfer image from PC memory to GPU memory
	                        cutilSafeCall( cudaMalloc( (void **)&d_imageDataChar, pImageReSized->widthStep * resizedImageHeight * sizeof(char)) );
	                        cutilSafeCall(cudaMemcpy(d_imageDataChar, pImageReSized->imageData, pImageReSized->widthStep * resizedImageHeight * sizeof(char), cudaMemcpyHostToDevice));              	                            
	                        
	                        imageCharToFloat(d_DataA_unpad,d_imageDataChar,pImageReSized->widthStep,resizedImageWidth,resizedImageHeight);
	                        
	                        //cutilSafeCall( cudaMemcpy(d_DataA_unpad, imag, resizedImageWidth*resizedImageHeight*sizeof(float), cudaMemcpyHostToDevice) );

	                        //pad the original image to reduce boundary effects
 	                        gabor.pad_GPU(d_DataA, d_DataA_unpad);  
                 	        
 	                        // center surround filter
	                        gabor.center_surround_GPU(d_DataA, d_DataA, gaussian_kernel_c, gaussian_kernel_s);  

	                        // Gabor filter
	                        gabor.gabor_GPU(d_padimgresult, d_DataA, gabor_kernel);  

	                        // remove padding
	                        gabor.cut_GPU(d_ResultGPU, d_padimgresult); 
	                        
	                        if(previousResult[ip]!=0)
    	                    { 	    
    	                        /*for(int x = 0; x < pImage->width* pImage->height; x++)
	                            {                                                                                                                                            
	                                   d_data_energy[x]=0;
	                            }*/
	                            //  timeStart = clock();
    	                         cutilSafeCall(cudaMemcpy(d_resultPrevious, previousResult[ip], resizedImageWidth*resizedImageHeight*sizeof(Complexgf), cudaMemcpyHostToDevice));              	                            
                	             gaborDistance(d_data_energy,d_resultPrevious,d_ResultGPU,resizedImageWidth,resizedImageHeight);
                	             
                	             // cutilSafeCall(cudaMemcpy(data_energy, d_data_energy, resizedImageWidth*resizedImageHeight*sizeof(float), cudaMemcpyDeviceToHost) );
                	              frontMovingSegment(d_data_energy,d_minColLocation,d_maxColLocation,resizedImageWidth,resizedImageHeight);
                	              cutilSafeCall(cudaMemcpy(minColLocation, d_minColLocation, resizedImageHeight*sizeof(int), cudaMemcpyDeviceToHost) );
                	              cutilSafeCall(cudaMemcpy(maxColLocation, d_maxColLocation, resizedImageHeight*sizeof(int), cudaMemcpyDeviceToHost) );
                	              
                	               cutilSafeCall(cudaFree(d_minColLocation));
                	               cutilSafeCall(cudaFree(d_maxColLocation));
                	               
                	             cutilSafeCall(cudaFree(d_resultPrevious));
                	             cutilSafeCall(cudaFree(d_data_energy));
                	           //  timeEnd= clock();
                	           //  printf("%d. Time Taken GPU energy:%.8fs, FPS:%.2f\n",ip,((timeEnd - timeStart)/(double)CLOCKS_PER_SEC),((double)CLOCKS_PER_SEC/(timeEnd - timeStart)));   //(end - start) / (double)CLOCKS_PER_SEC
                	        }
    	                    //gabor.andImage_GPU(d_ResultGPU,d_ResultGPU,
	                        // transfer result from GPU to PC
	                        cutilSafeCall( cudaMemcpy(result, d_ResultGPU, resizedImageWidth*resizedImageHeight*sizeof(Complexgf), cudaMemcpyDeviceToHost) );

                            cutilSafeCall(cudaFree(d_imageDataChar));
                             cutilSafeCall( cudaFree(d_ResultGPU) );
	                         cutilSafeCall( cudaFree(d_padimgresult) );
	                         cutilSafeCall( cudaFree(d_DataA) );
	                         cutilSafeCall( cudaFree(d_DataA_unpad) );
        		             gpuMutex.unlock();
        		             
        		             gpuTimeEnd = clock();
        		             gpuTimeSURFStart  = clock();         		          
        		             gpuTimeSURFEnd=gpuTimeSURFStart;
		                     //cutilSafeCall(cudaFreeHost(imag));
		                    
    		                 
		                  //   cutilSafeCall(cudaFreeHost(result));   //must be added later
                             // COMPUTE ORIENTATION ENERGY
                               
	                        //float *data_energyCPU = (float*)malloc(pImage->width* pImage->height * sizeof(float));  
	                        float max_energy = 0;
                            //gabor.~Gabor();
        		            
		                  //  cameraMutex.lock();
                            if(previousResult[ip]!=0)
    	                    {
    	                       /* IplImage* energyImage = cvCreateImage(cvSize(resizedImageWidth,resizedImageHeight),pImageReSized->depth,pImageReSized->nChannels);
    	                        for(int y=0; y < resizedImageHeight;y++)
	                            {
	                              for(int x = 0; x < resizedImageWidth; x++)
		                          {
		                              if( data_energy[y*resizedImageWidth+x] >1)
		                              {
		                                    energyImage->imageData[y*pImageReSized->widthStep+x]=255;
		                              }
		                              else
		                              {
		                                   energyImage->imageData[y*pImageReSized->widthStep+x]=0;
		                              }
		                          
		                          }
	                            
	                            } 
	                            if(frameNoGlobal[ip]==9)
	                            {
	                                cvSaveImage("FrameNo9.jpg",pImageReSized);
	                                cvSaveImage("DiparityGreater9.jpg",energyImage); 
	                            }
	                            cvShowImage("energyImage",energyImage);
	                            cvWaitKey(2);
	                            cvReleaseImage(&energyImage);    
	                            */
    	                    
    	                     /*   for(int x = 0; x < pImage->width* pImage->height; x++)
    	                        {
    	                            //   printf("X: %.2f, Y: %.2f\n",previousResult[ip][x].x,previousResult[ip][x].y);
    	                        } 
    	                       //timeStart = clock();
    	                        for(int x = 0; x < pImage->width* pImage->height; x++)
	                            {
	                                float xDiff =  result[x].x-previousResult[ip][x].x;
	                                float yDiff = result[x].y-previousResult[ip][x].y;
	                                if(xDiff>0.00001||yDiff>0.00001)
	                                {
	                                   // printf("X: %.2f, Y: %.2f\n",xDiff,yDiff);
	                                }
	                               // data_energyCPU[x] = sqrt(xDiff*xDiff+yDiff*yDiff);
	                                
	                                /*float error =floor(abs((data_energyCPU[x]-data_energy[x]))+0.5);
	                                if(error!=0)
	                                {
	                                    cout<<"CPU_GPU diff :"<<data_energyCPU[x]<<" "<<data_energy[x]<<endl;
	                                }* /
	                               
	                            }  */
	                         //  timeEnd= clock(); 
	                           //   printf("%d. Time Taken:%.2fs, FPS:%.2f\n",ip,((timeEnd - timeStart)/(double)CLOCKS_PER_SEC),((double)CLOCKS_PER_SEC/(timeEnd - timeStart)));   //(end - start) / (double)CLOCKS_PER_SEC
	                           
	                            free(previousResult[ip]);
	                            previousResult[ip]=0;
	                      
    	                    }
                	        
    	                    if(previousResult[ip]==0)                         
                            {    	        
                                previousResult[ip]=(Complexgf*)malloc(resizedImageWidth* resizedImageHeight * sizeof(Complexgf));
    	                        memcpy(previousResult[ip],result,resizedImageWidth* resizedImageHeight * sizeof(Complexgf));
    	                    }
    	                    cutilSafeCall(cudaFreeHost(result));
    	                 //   cutilSafeCall(cudaFreeHost(data_energy));
    	                    // gpuMutex.unlock();
		                  //  cameraMutex.unlock();
        		            
        		            
        		           /*
        		            
    		                // allocate memory for output image
	                        IplImage *resultImg_energy;
	                        resultImg_energy = cvCreateImage(cvSize(pImage->width,pImage->height),IPL_DEPTH_8U, 1);
    	                     */         
	                         int xMin=resizedImageWidth,yMin=resizedImageHeight,xMax=0,yMax=0;
    	                    
	                        int line1=0,line2=0;
                            bool lineEmpty=true;
                            /*
                            for(int y = (pImage->height-1); y >=0; y--)
	                        {
	                            lineEmpty=true;
		                        for(int x = 0; x < pImage->width; x++)
		                        {    		            
			                        //resultImg_energy->imageData[y*pImage->widthStep+x] = (char)(data_energy[y*pImage->width+x] / max_energy * 255);
			                        resultImg_energy->imageData[y*pImage->widthStep+x] =(char)0;
			                        if(data_energy[y*pImage->width+x]>3)
		                            {      
		                                lineEmpty = false;
		                                if(line1==0||line2==0)
		                                {
                                           // outPutFile<<data_energy[y*pImage->width+x]<<", ";                        
		                                    resultImg_energy->imageData[y*pImage->widthStep+x] =(char)255;
		                                     xMin = min(x,xMin);
        		                       
	                                        yMin =min(y,yMin);
    	                                    
	                                        xMax = max(x,xMax); 		                        
	                                        yMax=max(y,yMax);
		                                }
		                                else
		                                {
		                                    resultImg_energy->imageData[y*pImage->widthStep+x] =(char)0;
		                                }
		                            }
            			        
		                        }
            		            
		                        if(line1==0||line2==0)
		                        {
		                            if(!lineEmpty)
		                            {
		                                if(y==(pImage->height-1))
		                                {
		                                    line1 = (pImage->height-1);
		                                }            		                
		                            }
		                            else
		                            {
		                                if(line1!=0&&(line1-1)!=y)
		                                {
		                                    line2=y;
		                                }
		                                else
		                                {
		                                    line1=y;
		                                }
		                            }
		                        }
		                        //outPutFile<<lineEmpty<<endl;
		                    }
		                    cutilSafeCall(cudaFreeHost(data_energy));
    		                 */
    		                 
		                  //  delete data_energyCPU;
		                    // plot images in windows
                            //cvNamedWindow("original img",1);
	                        //cvShowImage("original img",pImage);
	                        /*IplImage *pImageAndEnergy = cvCreateImage(cvSize(pImage->width,pImage->height),IPL_DEPTH_8U, 1);;
    	           
                           cvAnd(pImage,resultImg_energy,pImageAndEnergy,0);*/
                             
                            for(int y = (resizedImageHeight-1); y >=0; y--)
	                        {
	                          //  printf("minColLocation :%d, maxColLocation :%d\n", minColLocation[y],maxColLocation[y] );
	                            if(line1==0||line2==0)
	                            {
	                                if( minColLocation[y]!=-1&&maxColLocation[y]!=-1)
	                                {
	                                    if(line1==0)
	                                    { 
	                                        line1=y;  
	                                    }
	                                    else if(line2==0)
	                                    {  
	                                        /*xMin = min(xMin,minColLocation[y]);
	                                        xMax = max(xMax,maxColLocation[y]); */   	                                
	                                    } 
	                                     xMin = min(xMin,minColLocation[y]);
	                                     xMax = max(xMax,maxColLocation[y]);
	                                         	                                
	                                }
	                                
	                                if(line1!=0&&minColLocation[y]==-1&&maxColLocation[y]==-1)
	                                {
	                                      line2=y+1;
	                                }
	                                
	                               /* if(line2==0&&line1!=0&&minColLocation[y]!=-1&&maxColLocation[y]!=-1)
	                                {
	                                    xMin = min(minColLocation[line1],minColLocation[y]);
	                                    xMax = max(maxColLocation[line1],maxColLocation[y]);
	                                     // line2=y+1;  
	                                }  */
	                            }
	                            else
	                            {
	                               break;
	                            }
	                        
	                        
	                        }
	                        
	                        //xMin = min(minColLocation[line1],minColLocation[line2]);
	                       // xMax = max(maxColLocation[line1],maxColLocation[line2]);
	                        
	                        yMax=  line1;
	                        yMin = line2;
	                        
	                         //cutilSafeCall(cudaFreeHost(minColLocation));
	                         //cutilSafeCall(cudaFreeHost(maxColLocation));
                             //gpuMutex.unlock();
                             
                             IplImage *pImageAndEnergy=0;
                             int xDiff =  xMax-xMin;
                            int yDiff = yMax-yMin;
                             bool pass=false;
                           // printf("\n\n\nXDifff:%d,YDiff:%d\n\n\n",xDiff,yDiff);
                           // if((xDiff>=100&&yDiff>=50)||(xDiff>=50&&yDiff>=100))
                            //if((xDiff>=100&&yDiff>=50)||(xDiff>=50&&yDiff>=100))
                            //if((xDiff>=200&&yDiff>=150)||(xDiff>=150&&yDiff>=200))
                            if((yMax!=(resizedImageHeight-1))&&(xDiff>=250&&yDiff>=250))
                           // if((xDiff>=250&&yDiff>=250))
                            {
                                pass=true;
                                /*if(xDiff<200||yDiff<200)
                                {
                                    int xMid = (xMin+xMax)/2;
                                    int yMid = (yMin+yMax)/2;
            	                    
                                    if(xDiff<200)
                                    {
                                        if((xMid-100)<0)
                                        {
                                            xMin=0;
                                            xMax=200;
                                        }
                                        else if((xMid+100)>resizedImageWidth)
                                        {
                                            xMin=resizedImageWidth-200;
                                            xMax=resizedImageWidth;
                                        }
                                        else
                                        {
                                           xMin= xMid-100;
                                           xMax = xMid+100;    	                        
                                        }           	                        
                                   
                                        xDiff=200;
                                    }
            	                    
                                    if(yDiff<200)
                                    {
                                        if((yMid-100)<0)
                                        {
                                            yMin=0;
                                            yMax=200;
                                        }
                                        else if((yMid+100)>resizedImageHeight)
                                        {
                                           yMin=resizedImageHeight-200;
                                            xMax=resizedImageHeight;
                                        }
                                        else
                                        {
                                            yMin=yMid-100;
                                            yMax=yMid+100;
                                        }
                                        yDiff = 200;
                                    }
                                }*/
                                
                               // printf("%d, %d\n", xDiff,yDiff );
                                cvSetImageROI(pImageReSized,cvRect(xMin,yMin,xDiff,yDiff));
		                        pImageAndEnergy = cvCreateImage(cvSize(xDiff,yDiff),IPL_DEPTH_8U, 1);
		                         /*for(int y=0;y<yDiff;y++)
		                        {
		                           int minTemp = minColLocation[yMin+y];
		                           int maxTemp = maxColLocation[yMin+y];
		                           
		                           for(int x=0;x<xDiff;x++)
		                           {
		                               //pImageReSized->imageData[y*pImage->widthStep+x]=0;//pImageAndEnergy->imageData[y*pImage->widthStep+x];
		                               
		                               if((xMin+x)>=minTemp&&(xMin+x)<=maxTemp)
		                               {
		                                    pImageAndEnergy->imageData[y*pImageAndEnergy->widthStep+x]=pImageReSized->imageData[(yMin+y)*pImageReSized->widthStep+(xMin+x)];
		                               }
		                               else
		                               {
		                                    pImageAndEnergy->imageData[y*pImageAndEnergy->widthStep+x]=0;
		                               }
		                              // pImageAndEnergy->imageData[y*pImageAndEnergy->widthStep+x]=0;
		                               
		                           } 
		                        }
		                        cvShowImage("Filled", pImageAndEnergy);
		                        cvWaitKey(2);   */
		                        cvCopy(pImageReSized,pImageAndEnergy); 
		                       			       
		                        cvResetImageROI(pImageReSized);
                            
                            
                            }
                            else
		                    {}
		                    cutilSafeCall(cudaFreeHost(minColLocation));
	                        cutilSafeCall(cudaFreeHost(maxColLocation));
		                   /* char ipAddress[15];
                            sprintf(ipAddress,"192.248.%d.0",(ip+1));
                            //cvShowImage("PIMAGE result energy img",pImage);
                            cvShowImage(ipAddress,pImageAndEnergy);                    
                            cvWaitKey(0);*/
                            /*cvShowImage("PIMAGE result energy img",pImageAndEnergy);
	                        if( cvWaitKey(10) >= 0 )                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                               break;*/
                              
                           // cvReleaseImage(&resultImg_energy);
                            
                            //SURFeatures surf;
                          //  DBConnect* dbConnect;
                           int objectNumOfKeypoints=0;
                           if(pass&&yMax>pYMaxArray[ip])     //
                          // if(pass)
                           {
                           
                                 gpuTimeSURFStart  = clock(); 
                                 gpuMutex.lock();
                                surf.setObject(pImageAndEnergy);
                                surf.extractSURFGPU(0);
                                objectNumOfKeypoints = surf.getObjectDescriptorsGpuMat().rows;
                               // cout<<"No of keyPoints :"<<objectNumOfKeypoints<<endl<<endl;   
                                //  gpuMutex.unlock(); 
                                
                                 if(objectNumOfKeypoints >100)   //180
                                {
                                    if(previousImage[ip]!=0)
                                    {
                                          //gpuMutex.lock();
                                        surf.setImage(previousImage[ip]);
                                        surf.extractSURFGPU(1);
                                        
                                        
                                        float matchError = surf.matchSURFGPU();
                                        cout<<"Match Error :"<<matchError<<endl;
                                       // surf.~SURFeatures();
                                        gpuMutex.unlock();
                                        gpuTimeSURFEnd  = clock(); 
                                        //cvWaitKey(10);
                                        if(matchError<0.52)
                                        {
                                            //cvShowImage(ipAddress,pImageAndEnergy);                    
                                            
                                             // add this to a different thread
                                           time_t timeNow;

                                            //DBConnect dbConnect("localhost","test","root","root");
                                          DBConnect* dbConnect = new DBConnect("localhost","test","root","root");
                                           char ipAddress[15];
                                           sprintf(ipAddress,"192.248.%d.0",(ip+10));
                                           timeNow=time(0);
                                           cvShowImage(ipAddress, pImageAndEnergy);
                                           cvWaitKey(1);
                                          // cout<< "Time 01:"<< timeNow<<endl;
                                           // cvShowImage("Before DB", pImageAndEnergy);
                                          //  printf("\nImage Size:%d\n\n",sizeof(pImageAndEnergy->imageData));
                                          
                                         /* char frameNo[50];
                                          sprintf(frameNo,"output\\%d.jpg",frameNoGlobal[ip]);
                                           cvSaveImage(frameNo,pImageAndEnergy);*/
                                          //std::stringstream sstr;
                                          //sstr << timeNow;  
                                          //  printf("Frame No before save :%s\n", frameNo);                           
                                          
                                           // cvWaitKey(1);  
                                           //sleep(1);
                                           
                                         //  IplImage* loadImage = cvLoadImage("651.jpg",CV_LOAD_IMAGE_GRAYSCALE);
                                           //for(;;)
                                           {
                                                dbConnect->storeMovingImage(ipAddress,pImageAndEnergy,&timeNow); //pImageAndEnergy                               
                                           }
                                          // dbConnect->storeMovingImage(ipAddress,pImage,&timeNow); //pImageAndEnergy                               

                                          
                                          //  dbConnect.~DBConnect(); 
                                           delete dbConnect;  
                                            
                                            
                                        
                                        }
                                         //gpuMutex.unlock();
                                        cvReleaseImage(&previousImage[ip]);
                                        previousImage[ip]=0;
                                       
                                    
                                    }
                                    else
                                    {
                                       gpuMutex.unlock();  
                                       gpuTimeSURFEnd  = clock();
                                    }
                                    if(previousImage[ip]==0)
                                    {
                                        previousImage[ip]=cvCloneImage(pImageAndEnergy);
                                       
                                        
                                    }
                                
                                     
                                }
                                else
                                {
                                    gpuMutex.unlock();    
                                    gpuTimeSURFEnd  = clock();    
                                }            
                                //cvWaitKey(1);
                               
                           }
                           pYMaxArray[ip]=yMax;
                            
                            cvReleaseImage(&pImageAndEnergy);
                            cvReleaseImage(&pImageReSized);
                          //  cvReleaseImage(&pRGBImageAndEnergy);
                    
                           /*SURFeatures* surf = new SURFeatures();
                            //SURFeatures surf;
                            surf->setObject(pImageAndEnergy);
                           /* //surf->setSrcCorners();
                           // surf->extractSURF(0);* /
                           surf->extractSURFGPU(0);
                           surf->~SURFeatures();* /
                           
                           /// delete surf;
                           char buf[50];
                            sprintf(buf,"output\\%d_SIFT.jpg", ip);
                            cvSaveImage(buf,pImageAndEnergy,0);
                            
                            cvShowImage(buf,pImageAndEnergy);
	                        if( cvWaitKey(10) >= 0 )                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                               break;
                            		
                           
                           /*SiftGPU  *sift = new SiftGPU();
                           // SiftGPU  sift;
                            int support = sift->CreateContextGL();
                             if(support != SiftGPU::SIFTGPU_FULL_SUPPORTED) 
                            {
                                cout<<"GPU not supported";
                            }//ilGetInteger(IL_IMAGE_FORMAT)
	                      //   sift.RunSIFT(pImage->width,pImage->height,pImage->imageData,GL_RGBA, GL_UNSIGNED_BYTE);
 	                         sift->RunSIFT(buf);
	                         int numOfFeatures = sift->GetFeatureNum();
    	                     
	                         if(numOfFeatures>0)
	                         {
	                            //allocate memory for readback
                               // vector<float > descriptors1(1);//, descriptors2(1);
                                //vector<SiftGPU::SiftKeypoint> keys1(1), keys2(1);    
	                         }
	                         //sift.~SiftGPU();
	                         delete sift;* /
    	                     
    	                    
    	                     
	                      //  cvDestroyWindow("PIMAGE result energy img");
    	                  
	                         cvReleaseImage(&pImageAndEnergy);
    		                 //cvReleaseImage(&resultImg_energy);
		                     //delete data_energy;
		                    /* cutilSafeCall( cudaFree(d_ResultGPU) );
	                         cutilSafeCall( cudaFree(d_padimgresult) );
	                         cutilSafeCall( cudaFree(d_DataA) );
	                         cutilSafeCall( cudaFree(d_DataA_unpad) );
        	                
        	               
        	                
        		            
    		               // gabor.~Gabor();
		                    cutilSafeCall(cudaFreeHost(result));
		                    cutilSafeCall(cudaFreeHost(imag));* /
		                    cout<<ip<<" :"<<frame->getFrameNo()<<endl;
    		               */ 
    		           }
    		              //end
    		            points.clear();
    		            delete frameArray[ip];
    		        
                    }
                    else
                    {
				        printf("Error Querying Frame on : %s\n",ipAddress);                    
                    }
    				

                    //if( cvWaitKey(10) >= 0 )                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
                     //   break;

                   // cameraMutex.lock();
                    //delete frameArray[ip];
                   // cameraMutex.unlock();
                   timeEnd = clock();
                  // printf("Frame No:%d\n",frameNoGlobal[ip]);
                  
                   printf("Frame No:%d, %d. Time Taken:%.2fs, FPS:%.2f\n",frameNoGlobal[ip],ip,((timeEnd - timeStart)/(double)CLOCKS_PER_SEC),((double)CLOCKS_PER_SEC/(timeEnd - timeStart)));   //(end - start) / (double)CLOCKS_PER_SEC
                    char outputFileName[40];
                    if(ip == 0)
                    {
                      sprintf(outputFileName,"output10.txt");
                    }
                    else if(ip==1)
                    {
                       sprintf(outputFileName,"output11.txt");
                    }
                    else if(ip==2)
                    {
                        sprintf(outputFileName,"output12.txt");
                    }
                    
                    ofstream outPutFile;
                    outPutFile.open (outputFileName, ios::app); 
                    outPutFile<<"FNum :"<<frameNoGlobal[ip]<<","<<ip<<","<<" GPU Time:,"<<((gpuTimeEnd+gpuTimeSURFEnd - gpuTimeStart-gpuTimeSURFStart)/(double)CLOCKS_PER_SEC)<<", Time Taken:,"<<((timeEnd - timeStart)/(double)CLOCKS_PER_SEC)<<endl;
                    outPutFile.close();
                    
                    /*outPutFile<<"FNum :"<<frameNoGlobal[ip]<<","<<ip<<","<<"FPS,"<<((double)CLOCKS_PER_SEC/(timeEnd - timeStart))<<endl;
                    outPutFile.close();*/
                    /*if(frameNoGlobal[ip]==1000)
                    {
                       break;
                    }*/
                   
                  /*  end=clock();
                    outPutFile<<"FNum "<<frameNo<<", "<<(end - start) / (double)CLOCKS_PER_SEC<<endl;
                    outPutFile.close();*/
                }
            }
            catch(exception& e)
            {
                printf("Exception on Thread ip Address: %s, Error:%s",ipAddress,e.what());
            }
           
        }
    }
};


//int _tmain(int argc, _TCHAR* argv[])
int main(int argc, char** argv)
{
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
cudaDeviceReset();

SURFeatures surf;
//_CrtSetBreakAlloc(138);

        //previousDescriptors = new float*[i];


        

		
int i=3;		 
//for (int i=0;i<=5;i++)  // was 100
{
    //imageArray= new  IplImage*[i];
   // frameArray = new Frame*[i];
    //http://www.tommesani.com/index.php?option=com_content&view=article&id=4:multi-thread-loops-with-intel-tbb&catid=3:multi-thread
   tbb::task_scheduler_init init(i);
    //init.initialize(10);
    
    try
    {
       // int frameNo=0;
      
        double sec=0.0;
        //time_t start, end;  // to control the frame rate
        clock_t start,end;

        
        IplImage* motion = 0;
       // char fileName[150];
        
       // sprintf(fileName,"E:\\CUDA\\Project\\Samples\\03.asf");
        //string fileName="E:\\CUDA\\Project\\Samples\\03.asf";
      // string fileName="D:\\Edu\\CUDA\\Project\\Samples\\03.asf";
        printf("Welcome to Object Tracking\n");

     // std::vector<pthread_t> id(i);
       /* pthread_t *threads;
        threads=(pthread_t *)malloc(i*sizeof(*threads));*/
       if (videoCollection==0)
       {
            videoCollection = new Video*[i];
            for (int j=0;j<i;j++)
            {
                videoCollection[j]=0;
            }
        }
        
   
        frameArray = new Frame*[i];
         frameNoGlobal = new int[i];
         for(int j=0;j<i;j++)
        {
             frameNoGlobal[j]=0;
        }
         
        //frameArray = new Frame*[500];
        bool once = false;
        
        tick_count t0 = tick_count::now();
        //vector<vector<float>> previousDescriptors(i,vector<float>(1));
        //vector<vector<float>> previousDescriptors(i,vector<float>(1,0));
        //vector<float>** previousDescriptors;//(i,vector<float>(1,0));'
        float** previousDescriptors;
        previousDescriptors = new float*[i];

        for(int j=0;j<i;j++)
        {
            previousDescriptors[j] =0;
        }
        
        int* numPrevious=new int[i];
        int* sizeOfPreviousDesciptors=new int[i];
        
        previousResult = new Complexgf*[i];
        for(int j=0;j<i;j++)
        {
            previousResult[j] =0;
        }
        previousImage = new IplImage*[i];
        for(int j=0;j<i;j++)
        {
            previousImage[j] =0;
        }
        pYMaxArray = new int[i];
        for(int j=0;j<i;j++)
        {
            pYMaxArray[j] =0;
        }
       //vector<vector<float>> previousDescriptors(i,vector<float>(0,0));
        //vector<vector<float>> previousDescriptors(vector<float>(1)(i));
        /*Gabor Filter GPU*/
            // DEFINE FILTER PARAMETERS AND COMPUTE KERNELS	
	        //parameter of gabor filter
	      /*  float omega = (float)2*PI/16;  // was 2*PI/16
	        float phi = (float)(1.005*PI/2);  //orientation  was *0/8

	        float sigmau = (float)2/omega;   //minor axis
	        float sigmav = (float)2*sigmau;  //major axis

	        // parameter of center surround filter	
	        float sigma_surround = (float)sigmau;
	        float sigma_center = (float)sigma_surround / 2;
	        
        	//create Filter_kernel objects for center surround filter
	        Filter_kernel gaussian_kernel_c(sigma_center, sigma_center, 0);
	        Filter_kernel gaussian_kernel_s(sigma_surround, sigma_surround, 0);

	        //create a Filter_kernel objects for Gabor filter
	        Filter_kernel gabor_kernel(sigmav, sigmau, phi, omega);*/
	        
	         /*clock_t timeStart,timeEnd;
             timeStart =  clock();  
             for(int ip=0;ip<i;ip++)
             {
		        pthread_create(&threads[ip], NULL, fetchFrames, (void*)ip);
             }     
      
             timeEnd =  clock(); 
             printf("Fetch feames:%.4fs\n",((timeEnd - timeStart)/(double)CLOCKS_PER_SEC));*/   //(end - start) / (double)CLOCKS_PER_SEC
           
        
     //  for(;;)
        //for(int l=0;l<4;l++)
        {     
             int d;
             
             printf("1. Fetch frames from Cameras\n");
             printf("2. Matcher\n");
             printf("Enter your option :");
             scanf("%d",&d);
           //  d=1;
             clock_t timeStart,timeEnd;
             timeStart =  clock();  
             if(d==1)
             {   
                tbb::parallel_for(blocked_range<int>(0,i),update());
                exit(0);
             }
             else if(d==2)
             {
                  //IplImage *image = cvLoadImage("E:\\CUDA\\Project\\Samples\\FromImages\\01.jpg",1);
                  IplImage *image =0;
                  //ObjectTracker*  objectTracker  = new ObjectTracker();
                  ObjectTracker  objectTracker;
                 // for(;;)
                  {
                  //  IplImage *grayImage = cvCreateImage(cvSize(image->width,image->height),image->depth,1);
                   // cvCvtColor(image,grayImage,CV_RGB2GRAY);                    
                    objectTracker.printMatchingFrames(image);
                   // cvReleaseImage(&image);
                   // cvReleaseImage(&grayImage);
                    
                  }
                 // delete  objectTracker;    
                  exit(0);
             }
             
             timeEnd =  clock(); 
             printf("Fetch feames:%.4fs\n",((timeEnd - timeStart)/(double)CLOCKS_PER_SEC));   //(end - start) / (double)CLOCKS_PER_SEC
            
            double fps=15;
            IplImage *image = cvLoadImage("E:\\CUDA\\Project\\Samples\\FromImages\\Square\\1.png",1);
            CvSize size = cvSize(image->width,image->height);
            CvVideoWriter* writer = cvCreateVideoWriter("Video from Images.avi",CV_FOURCC('D','I','V','X'),fps,size);   
            
            char fileName[200];
            
             for(int counter=0;counter<15;counter++)
             {
                if(counter<9)
                {
                    sprintf(fileName,"E:\\CUDA\\Project\\Samples\\FromImages\\Square\\%d.png",(counter+1));
                }
                else
                {
                   sprintf(fileName,"E:\\CUDA\\Project\\Samples\\FromImages\\Square\\%d.png",(counter+1));
                }
                    printf("%s",fileName);
                    
                    cvReleaseImage(&image);
                    image = cvLoadImage(fileName,1);
                  //  for(int i=0;i<3;i++)
                    { 
                        cvWriteFrame(writer, image);
                    }
             }
             cvReleaseVideoWriter(&writer);
             cvReleaseImage(&image);
             cvWaitKey(0);
             exit(0);
            
            
           /*Gabor Filter GPU*/
            // DEFINE FILTER PARAMETERS AND COMPUTE KERNELS	
            //parameter of gabor filter
            
            float omega = (float)2*PI/16;  // was 2*PI/16
            float phi = (float)(1.005*PI/2);  //orientation  was *0/8

            float sigmau = (float)2/omega;   //minor axis
            float sigmav = (float)2*sigmau;  //major axis

            // parameter of center surround filter	
            float sigma_surround = (float)sigmau;
            float sigma_center = (float)sigma_surround / 2;
	        
            //create Filter_kernel objects for center surround filter
            Filter_kernel gaussian_kernel_c(sigma_center, sigma_center, 0);
            Filter_kernel gaussian_kernel_s(sigma_surround, sigma_surround, 0);

            //create a Filter_kernel objects for Gabor filter
            Filter_kernel gabor_kernel(sigmav, sigmau, phi, omega);
	     
            
	        for(int p=0;p<i;p++)
	        {
	             timeStart =  clock();
             //    timeStart =  clock();                   
                
	        
	           // start = clock();
	            // convert image from char to float
	            float *imag;
	            IplImage *pImage=frameArray[p]->getGrayFrame();
	            IplImage *pRGBImage=frameArray[p]->getFrame();
	            //printf("Frame No :%d\n",frameNoGlobal[p]);
	            
	           /* if(  frameNoGlobal[p]==44)
	            {  
	              printf("");
	            }*/
    	        //
    	        if(pImage!=0)
    	        {
                    cutilSafeCall( cudaMallocHost( (void **)&imag, pImage->width* pImage->height * sizeof(float)));
					for(int y = 0; y < pImage->height; y ++)
                    {
                        for(int x = 0; x < pImage->width; x ++)
                        {
                            imag[y*pImage->width+x] = (float)(unsigned char)pImage->imageData[y*pImage->widthStep+x];
                        }
                    } 
	                
	                
	                 //memcpy(imag, (float*)pImageMat.data,pImage->width*pImage->height*sizeof(float));	           
	                
	               // copy(pImage->imageData,pImage->imageData+pImage->width* pImage->height,imag);
	                
	                 timeEnd =  clock(); 
                    printf("%d. Copy to Gabor:%.4fs\n",p,((timeEnd - timeStart)/(double)CLOCKS_PER_SEC));   //(end - start) / (double)CLOCKS_PER_SEC
                    timeStart =  clock();
        		    
	                // ALLOCATE MEMORY FOR COMPLEX OUTPUT OF GABOR FILTER

                    Complexgf *result; 
                     cutilSafeCall( cudaMallocHost( (void **)&result, pImage->width* pImage->height * sizeof(Complexgf)));
                   // result[0] = new Complexgf();
                   // cutilSafeCall( cudaMallocHost( (void **)result[0], pImage->width* pImage->height * sizeof(Complexgf)));
        	        
                    // CREATE FILTER OBJECT FOR PROCESSING IMAGE WITH SIZE OF INPUT

                    Gabor gabor(pImage->width, pImage->height,i);
                    //Gabor* gabor = new Gabor(pImage->width,pImage->height);
        	        
                    //ALLOCATE GPU MEMORY FOR PARAMETERS FOR PROCESSING

                    float
	                    *d_DataA_unpad,
	                    *d_DataA;

                    Complexgf
	                    *d_padimgresult,
	                    *d_ResultGPU;
        		        
	                cutilSafeCall( cudaMalloc( (void **)&d_DataA_unpad, gabor.DATA_SIZE_ori_f) );
                    cutilSafeCall( cudaMalloc( (void **)&d_DataA, gabor.DATA_SIZE_pad_f) );
                    cutilSafeCall( cudaMalloc( (void **)&d_padimgresult, gabor.DATA_SIZE_pad_c) );
                    cutilSafeCall( cudaMalloc( (void **)&d_ResultGPU, gabor.DATA_SIZE_ori_c) );

                    // PERFORM THE CENTER SURROUND AND GABOR FILTERING
        		
                    // transfer image from PC memory to GPU memory
                    cutilSafeCall( cudaMemcpy(d_DataA_unpad, imag, pImage->width*pImage->height*sizeof(float), cudaMemcpyHostToDevice) );
                  //  cutilSafeCall( cudaMemcpy(d_DataA_unpad, pImage->imageData, pImage->width*pImage->height*sizeof(float), cudaMemcpyHostToDevice) );

                    //pad the original image to reduce boundary effects
                    gabor.pad_GPU(d_DataA, d_DataA_unpad); 
                   // gabor.pad_GPU_ND(d_DataA, d_DataA_unpad);   
         	        
                    // center surround filter
                    gabor.center_surround_GPU(d_DataA, d_DataA, gaussian_kernel_c, gaussian_kernel_s);  
                   // gabor.center_surround_GPU_ND(d_DataA, d_DataA, gaussian_kernel_c, gaussian_kernel_s);  

                    // Gabor filter
                    gabor.gabor_GPU(d_padimgresult, d_DataA, gabor_kernel);  
                    //gabor.gabor_GPU_ND(d_padimgresult, d_DataA, gabor_kernel);  

                    // remove padding
                    gabor.cut_GPU(d_ResultGPU, d_padimgresult); 
        	        
	                //gabor.andImage_GPU(d_ResultGPU,d_ResultGPU,
                    // transfer result from GPU to PC
                    cutilSafeCall( cudaMemcpy(result, d_ResultGPU, pImage->width*pImage->height*sizeof(Complexgf), cudaMemcpyDeviceToHost) );

                     cutilSafeCall( cudaFree(d_ResultGPU) );
                     cutilSafeCall( cudaFree(d_padimgresult) );
                     cutilSafeCall( cudaFree(d_DataA) );
                     cutilSafeCall( cudaFree(d_DataA_unpad) );
        		            
        		            
	                 cutilSafeCall(cudaFreeHost(imag));
    		         
                     // COMPUTE ORIENTATION ENERGY

                    float *data_energy = (float*)malloc(pImage->width* pImage->height * sizeof(float));  
                    float max_energy = 0; 
                  //  gabor->~Gabor();
                   
        	        

	                if(previousResult[p]!=0)
	                {
	                    for(int x = 0; x < pImage->width* pImage->height; x++)
                        {
                            float xDiff =  result[x].x-previousResult[p][x].x;
                            float yDiff = result[x].y-previousResult[p][x].y;
                            data_energy[x] = sqrt (xDiff*xDiff+yDiff*yDiff);
    	                    
                           /* if(data_energy[x] > max_energy) 
	                        {
		                         max_energy = data_energy[x];
		                        // max_energy = 255;
	                        }*/
                        }
                        free(previousResult[p]);
                        previousResult[p]=0;
	                }
        	        
	                if(previousResult[p]==0)
                    {    	        
                        previousResult[p]=(Complexgf*)malloc(pImage->width* pImage->height * sizeof(Complexgf));
                        memcpy(previousResult[p],result,pImage->width* pImage->height * sizeof(Complexgf));
	                }
                    cutilSafeCall(cudaFreeHost(result));
	               // previousResult = 
                    //NORMALIZE ENERGY FOR DISPLAY AS IMAGE
                    
                    // allocate memory for output image,  not used anymore remove later
                    IplImage *resultImg_energy;
                    resultImg_energy = cvCreateImage(cvSize(pImage->width,pImage->height),IPL_DEPTH_8U, 1);
    	            
	               // vector<Point> points;  // for convex hull
        	        
	               // ofstream outPutFile;
        	        
        	        timeEnd =  clock(); 
                    printf("%d. Time Gabor:%.4fs\n",p,((timeEnd - timeStart)/(double)CLOCKS_PER_SEC));   //(end - start) / (double)CLOCKS_PER_SEC
                    timeStart =  clock();
            
                    int xMin=pImage->width,yMin=pImage->height,xMax=0,yMax=0;
                    int line1=0,line2=0;
                    bool lineEmpty=true;
                    //for(int y = 0; y < pImage->height; y++)
                    for(int y = (pImage->height-1); y >=0; y--)
                    {
                        lineEmpty=true;
	                    for(int x = 0; x < pImage->width; x++)
	                    {    		            
		                    //resultImg_energy->imageData[y*pImage->widthStep+x] = (char)(data_energy[y*pImage->width+x] / max_energy * 255);
		                    resultImg_energy->imageData[y*pImage->widthStep+x] =(char)0;
		                    if(data_energy[y*pImage->width+x]>3)
	                        {      
	                            lineEmpty = false;
	                            if(line1==0||line2==0)
	                            {
                                   //    outPutFile<<data_energy[y*pImage->width+x]<<", ";                        
	                                resultImg_energy->imageData[y*pImage->widthStep+x] =(char)255;
    		                        
	                                xMin = min(x,xMin);
    		                       
	                                yMin =min(y,yMin);
	                                /*if(yMinTemp>0)
	                                { 
	                                    yMin = yMinTemp;
	                                }*/
	                               // yMin = min(y,yMin); 
    		                         	
	                                xMax = max(x,xMax); 		                        
	                                yMax=max(y,yMax);
    		                        
	                                /*xMax = 
	                                if(y<yMin)
	                                {
	                                   yMin = y;
	                                }
	                                if(y>yMax)
	                                {
	                                   yMax=y;		                        
	                                } */
    		                        
	                            }
	                            else
	                            {
	                                resultImg_energy->imageData[y*pImage->widthStep+x] =(char)0;
	                            }
	                        }
    			        
	                    }
    		            
	                    if(line1==0||line2==0)
	                    {
	                        if(!lineEmpty)
	                        {
	                            if(y==(pImage->height-1))
	                            {
	                                line1 = (pImage->height-1);
	                            }
        		                
	                        }
	                        else
	                        {
	                            if(line1!=0&&(line1-1)!=y)
	                            {
	                                line2=y;
	                            }
	                            else
	                            {
	                                line1=y;
	                            }
	                        }
	                    }
	                  //  outPutFile<<lineEmpty<<endl;
	                }
    		        
	                 delete data_energy;
	                //outPutFile<<endl<<endl<<line1<<" "<<line2<<endl;
		           // outPutFile.close();
	                // DISPLAY ORIGINAL IMMAGE AND NORMALIZED ENERGY
        	
                    // plot images in windows
                    //cvNamedWindow("original img",1);
                    //cvShowImage("original img",pImage);
                    //cvNamedWindow("result energy img",1);
                   /// cvShowImage("result energy img",resultImg_energy);
    	            
                    IplImage *pImageAndEnergy=0;
                    IplImage* pRGBImageAndEnergy=0; 
                    int xDiff =  xMax-xMin;
                    int yDiff = yMax-yMin;	
                    
                    bool pass=false; 
    	                       
                   if((xDiff>=100&&yDiff>=50)||(xDiff>=50&&yDiff>=100))
                    {
                        pass=true;
                         if(xDiff<200||yDiff<200)
                        {
                            int xMid = (xMin+xMax)/2;
                            int yMid = (yMin+yMax)/2;
    	                    
                            if(xDiff<200)
                            {
                                if((xMid-100)<0)
                                {
                                    xMin=0;
                                    xMax=200;
                                }
                                else if((xMid+100)>pImage->width)
                                {
                                    xMin=pImage->width-200;
                                    xMax=pImage->width;
                                }
                                else
                                {
                                   xMin= xMid-100;
                                   xMax = xMid+100;    	                        
                                }
    	                        
                               /* if((xMid-100)>0)
                                {
                                    xMin = xMid-100;
                                    xMax = xMid+100;
                                }
                                else if((xMid+100)>pImage->width)
                                {
                                    xMin = 0;
                                    xMax = 200;
                                }*/
                                xDiff=200;
                            }
    	                    
                            if(yDiff<200)
                            {
                                if((yMid-100)<0)
                                {
                                    yMin=0;
                                    yMax=200;
                                }
                                else if((yMid+100)>pImage->height)
                                {
                                   yMin=pImage->height-200;
                                    xMax=pImage->height;
                                }
                                else
                                {
                                    yMin=yMid-100;
                                    yMax=yMid+100;
                                }
                                yDiff = 200;
                            }
                        }
                        //cvSetImageROI(pImage,cvRect(xMin,yMin,(xMax-xMin),(yMax-yMin)));
		                //pImageAndEnergy = cvCreateImage(cvSize((xMax-xMin),(yMax-yMin)),IPL_DEPTH_8U, 1);
		                cvSetImageROI(pImage,cvRect(xMin,yMin,xDiff,yDiff));
		                pImageAndEnergy = cvCreateImage(cvSize(xDiff,yDiff),IPL_DEPTH_8U, 1);
		                cvCopy(pImage,pImageAndEnergy); 			       
		                cvResetImageROI(pImage);
    			        
		                cvSetImageROI(pRGBImage,cvRect(xMin,yMin,xDiff,yDiff));
		                pRGBImageAndEnergy = cvCreateImage(cvSize(xDiff,yDiff),IPL_DEPTH_8U, 3);
		                cvCopy(pRGBImage,pRGBImageAndEnergy);
		                cvResetImageROI(pRGBImage);
    			        
		               // cvShowImage("PIMAGE result energy img",pImageAndEnergy);
                       // cvWaitKey(0);  
                            
		            }
		            else
		            {        
		                //this block is not used any more 
		                /*       
                        pImageAndEnergy = cvCreateImage(cvSize(pImage->width,pImage->height),IPL_DEPTH_8U, 1);
                    //resultImg_energy = cvCreateImage(cvSize(pImage->width,pImage->height),IPL_DEPTH_8U, 1);
    	           
                        cvAnd(pImage,resultImg_energy,pImageAndEnergy,0);
                        
                        pRGBImageAndEnergy = cvCreateImage(cvSize(pRGBImage->width,pRGBImage->height),IPL_DEPTH_8U, 3);
                        
                        IplImage* resultImg_energyThreeChannel = cvCreateImage(cvSize(pRGBImage->width,pRGBImage->height),IPL_DEPTH_8U, 3);
                        cvMerge(resultImg_energy , NULL, NULL, NULL, resultImg_energyThreeChannel);
                        cvAnd(pRGBImage,resultImg_energyThreeChannel,pRGBImageAndEnergy,0);
                        cvReleaseImage(&resultImg_energyThreeChannel);
                        */
                        
                    }
                    /*char ipAddress[15];
                    sprintf(ipAddress,"192.248.%d.0",(p+1));*/
                   // cvShowImage(ipAddress,pRGBImageAndEnergy);                    
                    //cvWaitKey(1);
                    /* if( cvWaitKey(10) >= 0 )  
                        break;*/
                    //cout<<"line1 :"<<line1<<", line2 :"<<line2<<endl;
                    cvReleaseImage(&resultImg_energy);
                    
               
                   /* cvRectangle(pImageAndEnergy,cvPoint(xMin,yMin),cvPoint(xMax,yMax),cvScalar(255,255,255),2,8,0);
	                  cvShowImage("Block",pImageAndEnergy);
                    cvWaitKey(10);*/ 
                    
                    
                    char buf[50];
                    sprintf(buf,"output\\%d_01.jpg", p);
                   // cvSaveImage(buf,pImageAndEnergy,0);
                   
                   timeEnd =  clock(); 
                    printf("%d. Find First Segment:%.4fs\n",p,((timeEnd - timeStart)/(double)CLOCKS_PER_SEC));   //(end - start) / (double)CLOCKS_PER_SEC
                    timeStart =  clock();
                  
                    	              
                   int objectNumOfKeypoints=0;
                   if(pass)
                   {
                        //SURFeatures* surf=new SURFeatures();
                        //SURFeatures surf;
                        surf.setObject(pImageAndEnergy);
                       /* //surf->setSrcCorners();
                       // surf->extractSURF(0);*/
                        surf.extractSURFGPU(0);
                                      
                       //delete surf;
                       // surf.~SURFeatures(); 
                       
                       //int objectNumOfKeypoints = surf.getKeypointsObjectSize();   getObjectKeyPointsGpuMat
                        objectNumOfKeypoints = surf.getObjectDescriptorsGpuMat().rows;
                        //cout<<"No of keyPoints :"<<objectNumOfKeypoints<<endl<<endl;                 
                   
                   
                   }
                 
                    
                   
                   
                    
                    
                    if(objectNumOfKeypoints >180)
                    {
                       
                         /*cvRectangle(pImageAndEnergy,cvPoint(xMin,yMin),cvPoint(xMax,yMax),cvScalar(255,255,255),2,8,0);
	                    cvShowImage("Block",pImageAndEnergy);
                        cvWaitKey(10);*/
                    
                        if(previousImage[p]!=0)
                        {
                               surf.setImage(previousImage[p]);
                               surf.extractSURFGPU(1);
                               
                                //cout<<"No Of Matchers :"<<surf.matchSURFGPU()<<endl;
                                //surf.matchSURFGPU();
                                float matchError = surf.matchSURFGPU();
                                cout<<"Match Error :"<<matchError<<endl;
                                //cvWaitKey(10);
                                if(matchError>0.5)
                                { 
                                /* vector<float> descriptorsObject, descriptorImage;
                               //./  descriptorsObject=
                                
                                float* descriptorsObjectArray = &surf.getDescriptorsObject()[0];
                                float* descriptorsImageArray  = &surf.getDescriptorImage()[0];
             
                                 euclideanDistance(descriptorsObjectArray,surf.getDescriptorsObject().size()*sizeof(float),descriptorsImageArray, surf.getDescriptorImage().size()*sizeof(float));
                               */
                               
                                //euclideanDistance();      
                                  /*ObjectTracker*  objectTracker  = new ObjectTracker();
                                  objectTracker->printMatchingFrames(pImageAndEnergy);*/ 
                                  
                                  
                                  
                                  
                                  /*
                                  
                                  // calculate the color code
                                   //pRGBImageAndEnergy
                                   list<int>* rgbBinValueList = new list<int>();
                            
    	                            
                                   // cvShowImage("Red",dist_Image [0]);
                                   // cvWaitKey(0);
    	                            
                                 //  pRGBImageAndEnergy = imread("E:\\CUDA\\Project\\Samples\\abc.bmp", CV_LOAD_IMAGE_COLOR);
    	                            
                                   cv::gpu::GpuMat pRGBImageAndEnergyGpuMat;
                                   pRGBImageAndEnergyGpuMat.upload(cv::Mat(pRGBImageAndEnergy)); //pRGBImageAndEnergy
                                 //  pRGBImageAndEnergyGpuMat.upload(cv::Mat(imread("E:\\CUDA\\Project\\Samples\\abc.bmp", CV_LOAD_IMAGE_COLOR))); //pRGBImageAndEnergy
                                   
                                   
                                                                 
                                   cv::gpu::GpuMat* rgbSplitImageGpuMat =new cv::gpu::GpuMat[pRGBImageAndEnergy->nChannels];
                                   //cv::gpu::GpuMat rgbSplitImageGpuMat[pRGBImageAndEnergy->nChannels];// = new cv::gpu::GpuMat[pRGBImageAndEnergy->nChannels];
                                  // cv::gpu::cvtColor(rgbSplitImageGpuMat,rgbSplitImageGpuMat,
                                   cv::gpu::split(pRGBImageAndEnergyGpuMat,rgbSplitImageGpuMat);
                                   
                                  // cv::gpu::split(
                                   cv::gpu::GpuMat* channelHistGpuMat = new cv::gpu::GpuMat[pRGBImageAndEnergy->nChannels];
                                   //cv::Mat* channelHistMat;
                                   
                                   for(int ch=0;ch<pRGBImageAndEnergy->nChannels;ch++)
                                   {
                                        
                                        cv::gpu::calcHist(rgbSplitImageGpuMat[ch],channelHistGpuMat[ch],cv::gpu::Stream::Null());
                                        int maxValue=0;
                                        //cv::Point*  minLoc, maxLoc;
                                        
                                       // channelHistMat[ch] = new cv::Mat(channelHistGpuMat[ch]);
                                        cv::Mat channelHistMat(channelHistGpuMat[ch]);    
                                         int maxPosition=-1;                            
                                        for(int ihist=0;ihist<256;ihist++)
                                        {
                                            int histValue = channelHistMat.at<int>(ihist);
                                            if(histValue>maxValue)
                                            {
                                               maxValue=histValue;
                                               maxPosition=ihist;
                                            }                                      
                                        }
                                        rgbBinValueList->push_back(maxPosition);
                                        channelHistMat.release();
                                      
                                        channelHistGpuMat[ch].release();
                                        rgbSplitImageGpuMat[ch].release();
                                        
                                        //cv::gpu::minMaxLoc(channelHistGpuMat,minValue, maxValue,minLoc,maxLoc,cv::gpu::GpuMat(),cv::gpu::GpuMat(),cv::gpu::GpuMat());
                                   
                                   }
                                   channelHistGpuMat->~GpuMat();
                                   rgbSplitImageGpuMat->~GpuMat();
                                   
                                   
                                   printf("Blue, Green, Red :");
                                   for(int iBin=0; iBin<pRGBImageAndEnergy->nChannels;iBin++)
                                   {
                                       printf("%d ",rgbBinValueList->front());
                                       rgbBinValueList->pop_front();
                                   }   
                                   
                                  ///printf("%d, %d, %d",rgbBinValueList[0],rgbBinValueList[1],rgbBinValueList[2]);
                                      printf("\n");
                                      //cvWaitKey(0);
                                     
                                     rgbBinValueList->clear();
                                     delete rgbBinValueList; 
                                     
                                     */    
                                   
                                   //cv::gpu::calcHist(&pRGBImageAndEnergyGpuMat,&histGpuMat,&cv::gpu::Stream::Null());
                                 //  cv::gpu::calcHist(rgbSplitImageGpuMat[0].,rHistGpuMat,cv::gpu::Stream::Null());
                        
                                    // add this to a different thread
                                   time_t timeNow;

                                   DBConnect* dbConnect = new DBConnect("localhost","test","root","root");
                                   char ipAddress[15];
                                   sprintf(ipAddress,"192.248.%d.0",(p+1));
                                   timeNow=time(0);
                                  // cout<< "Time 01:"<< timeNow<<endl;
                             
                                  
                                   dbConnect->storeMovingImage(ipAddress,pImageAndEnergy,&timeNow); 
                              
                                   

                                  
                                   
                                   delete dbConnect;    
                                }
                                
                                cvReleaseImage(&previousImage[p]);
                                previousImage[p]=0;
                        }
                        
                        if(previousImage[p]==0)
                        {
                           previousImage[p]=cvCloneImage(pImageAndEnergy);
                        }
                        
                    
                    }
                      cvReleaseImage(&pImageAndEnergy);
                      cvReleaseImage(&pRGBImageAndEnergy);
                  }
                  //end
                // surf->getObjectKeyPointsGpuMat().cols;
                  // surf->getObjectDescriptorsGpuMat().cols;
                
                /*SiftGPU  *sift = new SiftGPU();
                //SiftGPU  sift;
                int support = sift->CreateContextGL();
                if(support != SiftGPU::SIFTGPU_FULL_SUPPORTED) 
                {
                    cout<<"";
                }
                
               // sift.RunSIFT(pImageAndEnergy->width,pImageAndEnergy->height,pImageAndEnergy->imageData,GL_RGBA, GL_UNSIGNED_BYTE);
               // sift.RunSIFT(pImageAndEnergy->width,pImageAndEnergy->height,pImageAndEnergy->imageData,GL_RGBA,0);
                sift->RunSIFT(buf);
                int numOfFeatures  = sift->GetFeatureNum();//
                
               // vector<float>* descriptors;
               // vector<SiftGPU::SiftKeypoint>* keys;
                
                if(numOfFeatures !=0)
                {
                   //allocate memory for readback
                    vector<float > descriptors1(1);//, descriptors2(1);
                    vector<SiftGPU::SiftKeypoint> keys1(1), keys2(1);    
                    // int num1, num2;
                    
                   keys1.resize(numOfFeatures);    descriptors1.resize(128*numOfFeatures);
                   sift->GetFeatureVector(&keys1[0], &descriptors1[0]);
               
                     if(previousDescriptors[p]!=0)
                     {
                       
                         SiftMatchGPU *matcher= new SiftMatchGPU(4096); 
                        // SiftMatchGPU matcher;
                          
   
                       matcher->VerifyContextGL(); //must call once
                       matcher->SetDescriptors(0, numOfFeatures, &descriptors1[0]);                       
                       matcher->SetDescriptors(1, numPrevious[p],previousDescriptors[p]); //&previousDescriptors[0] &previousDescriptors.at(i).at(0)
                        
                       //Match and read back result to input buffer
                        int (*match_buf)[2] = new int[numOfFeatures][2];
                        int nmatch = matcher->GetSiftMatch(4096, match_buf);
                        cout<<"Num 01:"<<numOfFeatures<<" ,NumPrevoius :"<<numPrevious[p]<<" ,N Match :"<<nmatch<<endl;
                        
                        if(nmatch>25)
                        {
                            DBConnect* dbConnect = new DBConnect("localhost","test","root","root");
                           // if(dbConnect->connect())
                            {
                            
                            char ipAddress[15];
                            sprintf(ipAddress,"192.248.%d.0",(p+1)); //int id,char* cameraIp,float* siftFeatures,int noOfSIFTFeatures,int discriptorSize,time_t timeStamp
                            SIFTFeature* siftFeature = new SIFTFeature(0,ipAddress,previousDescriptors[p],numPrevious[p],sizeOfPreviousDesciptors[p],pImage,time(0));
                            
                            siftFeature->saveToDB(dbConnect);
                           
                            
                            
                            //siftFeature->loadById(dbConnect,485);
                             delete siftFeature;
                          
                            }
                            delete dbConnect;
                        }
                        delete match_buf[0];
                        delete match_buf[1];
                        delete[] match_buf;
                        delete matcher;
                     }
                     
                     
                     
                  
                     if(previousDescriptors[p]!=0)
                     {
                        delete previousDescriptors[p];
                        
                        previousDescriptors[p]=0;
                        //previousDescriptors[p].clear();
                     }
                 
                     if(previousDescriptors[p]==0)
                     {
                        previousDescriptors[p]=new float[descriptors1.size()];
                        //previousDescriptors[p]=(float*)malloc(descriptors1.size() * sizeof(float));
                       // previousDescriptor=descriptor;
                        memcpy(previousDescriptors[p],&descriptors1[0],descriptors1.size() * sizeof(float));
                        numPrevious[p]=numOfFeatures;   
                        sizeOfPreviousDesciptors[p] = descriptors1.size();
                         
                      
                     }
                   descriptors1.clear(); 
                   keys1.clear();
                   keys2.clear();  
                }
                
                
               
                
                
   
	         
	          // cvWaitKey();
                
                delete sift;
              // sift.~SiftGPU();
               */
               
                points.clear();
	            // deallocate resources
	            //cvDestroyWindow("original img");
	            //cvDestroyWindow("result energy img");
	            //cvReleaseImage(&pImage);
	            /*cvReleaseImage(&resultImg_energy);
	            free(data_energy);
	            cutilSafeCall( cudaFreeHost(result) );
	            cutilSafeCall( cudaFreeHost(imag) );
	            cutilSafeCall( cudaFree(d_DataA_unpad) );
	            cutilSafeCall( cudaFree(d_DataA) );
	            cutilSafeCall( cudaFree(d_padimgresult) );
	            cutilSafeCall( cudaFree(d_ResultGPU) );*/
	            //cout<<p<<" :"<<frameArray[p]->getFrameNo()<<endl;
	            delete frameArray[p];
	           
                  // delete surf;
	            timeEnd =  clock(); 
                printf("Time Taken:%.4fs\n",((timeEnd - timeStart)/(double)CLOCKS_PER_SEC));   //(end - start) / (double)CLOCKS_PER_SEC
            
            }
           /* timeEnd = clock();
            printf("Time Taken:%.2fs, FPS:%.2f\n",((timeEnd - timeStart)/(double)CLOCKS_PER_SEC),((double)CLOCKS_PER_SEC/(timeEnd - timeStart)));   //(end - start) / (double)CLOCKS_PER_SEC
             */
            //_CrtSetBreakAlloc(136);

            
        }
        /* Image copy GPU*/
        delete frameNoGlobal;
        delete frameArray;
    
		 /*tbb::tick_count t1 = tick_count::now();
		 printf("\nNo threads :%d, work took %g seconds\n",i,(t1-t0).seconds());*/
		 
		
        for(int j=0;j<i;j++)
        {
               free(previousResult[j]);
        }
		delete previousResult;
		
		delete sizeOfPreviousDesciptors;
		delete numPrevious;
		 
		 if(previousDescriptors!=0)
		 {
		    delete previousDescriptors;
		 }
		 
       if (videoCollection!=0)
       {            
            for (int j=0;j<i;j++)
            {
                delete videoCollection[j];
            }
            delete videoCollection;
        }
    
	
    }
    catch(exception& e)
    {
        printf("Exception: %s",e.what());
    }

}
    _CrtDumpMemoryLeaks();
    return 0;
}

bool imageCopyCPU(unsigned char* src,unsigned char* dest,int width,int height,size_t size,int noOfImages)
{
    int imageSize = width*height;
     
	const float lpf[2]={-1, 1};
	
    for(int imCount=0;imCount<noOfImages;imCount++)
    {
        for(int i=1;i<width;i++)
        {
            for(int j=0;j<height;j++)
            {
                
              //  dest[imCount*imageSize+i+width*j] = src[imCount*imageSize+i+width*j] - src[imCount*imageSize+i+width*j-1];
               dest[imCount*imageSize+i+width*j] = src[imCount*imageSize+i+width*j];
            }
        }
    }
    
    return true;

}